﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace AllDemo
{
    public partial class 线性回归可视化 : Form
    {
        public 线性回归可视化()
        {
            InitializeComponent();
        }
       
       
       
            private void button2_Click(object sender, EventArgs e)
            {
                OpenFileDialog openFileDialog1 = new System.Windows.Forms.OpenFileDialog();//一个打开文件的对话框  
                openFileDialog1.Filter = "文本文件(*.txt)|*.txt";//设置允许打开的扩展名  
                if (openFileDialog1.ShowDialog() == DialogResult.OK)//判断是否选择了文件    
                {
                    string txt_FilePath = openFileDialog1.FileName;//打开文件的路径           
                    StreamReader streamReader = new StreamReader(txt_FilePath, Encoding.Default);//记录用户选择的文件路径
                                                                                                 //存储数组
                    string list = "";
                    while (!streamReader.EndOfStream)
                    {//如果这个还没有读到文件尾
                        string line = streamReader.ReadLine();//就一行一行地读

                        list += line;

                    }
                    //richTextBox1.Text = list;
                    //字符串转换
                    string[] sNums = list.Split(new char[] { ',' });
                    double[] iNums = new double[sNums.Length];
                    for (int i = 0; i < sNums.Length; i++)
                    {
                        iNums[i] = double.Parse(sNums[i]);
                    }
                    //iNums = Array.ConvertAll(sNums, int.Parse);
                    //for (int i = 0; i < sNums.Length; i++)
                    //    richTextBox1.Text += sNums[i];
                    //绘图
                    //绘制点
                    Graphics g = CreateGraphics();
                    //利用循环
                    int x_s = 100;
                    int y_s = 300;

                    for (int i = 0; i < iNums.Length / 2; i++)
                    {
                        int x = (int)(iNums[i] + x_s);
                        int y = (int)(iNums[i + iNums.Length / 2] + y_s);
                        g.FillEllipse(Brushes.Black, x, y, 10, 10);
                        x_s = x_s + 20;
                        y_s = y_s - 20;
                    }
                    //绘制最小二乘曲线
                    //最小二乘曲线算法 y=bx+a
                    //求均值
                    double averagex = 0, averagey = 0, allx = 0, ally = 0;
                    for (int i = 0; i < iNums.Length / 2; i++)
                    {
                        allx += iNums[i];
                        ally += iNums[i + iNums.Length / 2];
                    }
                    averagex = allx / (iNums.Length / 2);
                    averagey = ally / (iNums.Length / 2);
                    //求截距与斜率
                    double numerator = 0;
                    double denominator = 0;
                    for (int i = 0; i < iNums.Length / 2; i++)
                    {
                        numerator += (iNums[i] - averagex) * (iNums[i + 10] - averagey);
                        denominator += (iNums[i] - averagex) * (iNums[i] - averagex);
                    }
                    //回归系数b（Regression Coefficient）
                    double RCB = numerator / denominator;
                    //回归系数a
                    double RCA = averagey - RCB * averagex;
                    //绘制回归曲线
                    //起始坐标
                    int x_q = (int)(iNums[0]) + 100;
                    int y_q = (int)(RCB * iNums[0] + RCA) + 300;
                    //终止坐标
                    int y_z = (int)(iNums[iNums.Length / 2] * RCA + RCB) - 260;
                    int x_z = (int)(iNums[iNums.Length / 2]) + 700;
                    //画线
                    Graphics graphics = CreateGraphics();
                    Pen pen = new Pen(Brushes.Red, 2);
                    graphics.DrawLine(pen, x_q, y_q, x_s, y_z);
                    //显示曲线方程
                    linkLabel1.Text = "Y=  " + RCA.ToString() + " + " + RCB.ToString() + "X";
                }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //绘制图形
            Font font = new System.Drawing.Font("Arial", 9, FontStyle.Regular);
            Graphics graphics = CreateGraphics();
            Pen pen = new Pen(Brushes.Black, 2);
            graphics.DrawLine(pen, 80, 360, 700, 360);//X
            graphics.DrawLine(pen, 80, 360, 80, 30);//Y
            //X轴标记
            String[] n = { "0.5", "1", "1.5", "2", "2.5", "3", "3.5", "4", "4.5", "5", "5.5", "6" };
            int xb = 90;
            for (int i = 0; i < 12; i++)
            {
                graphics.DrawString(n[i].ToString(), font, Brushes.Red, xb, 360); //设置文字内容及输出位置

                xb = xb + 55;
            }

            //Y轴标记
            String[] m = { "100", "90", "80", "70", "60", "50", "40", "30", "20", "10" };
            int y = 60;
            for (int i = 0; i < 10; i++)
            {
                graphics.DrawString(m[i].ToString(), font, Brushes.Red, 50, y); //设置文字内容及输出位置
                y = y + 30;
            }

        }
    }
}
